// 权限验证中间件
const jwt = require('jsonwebtoken');
const { jwtSecret } = require('../utils/jwtUtils');
const sendResponse = require('../utils/response');

// 引入模型
const User = require('../models/user.model');
const Role = require('../models/role.model');
const Menu = require('../models/menu.model');
const { where } = require('sequelize');

// 获取用户信息
async function getUserFromToken(req) {  
  // 从请求头获取 token
  const token = req.header('Authorization');

  if (!token) throw new Error('Missing token');

  // 验证并解码 token
  const decoded = jwt.verify(token, jwtSecret);

  // 从数据库获取完整用户信息
  const user = await User.findByPk(decoded.id, {
    attributes: ['id', 'username']  // 只返回 id、username、status 三个字段
  });

  // 验证用户是否存在或是否被禁用
  if (!user || user.status === 0) throw new Error('Invalid user');
  return user;
}

// 获取用户权限
async function getPermissions(userId) {
  // 获取用户角色
  const user = await User.findByPk(userId, {
    as: 'Users',
    include: {
      model: Role,
      as: 'Roles',
      include: [{
        model: Menu,
        as: 'Menus'
      }] 
    }
  });
  
  // 获取用户权限code，并且level不等于4的，去除空字符
  const menusArr = [...new Set(user.Roles.flatMap(r => r.Menus.map(m => m.level !== 4 ? m.code : '')))]
  const buttonArr = [...new Set(user.Roles.flatMap(r => r.Menus.map(m => m.level == 4 ? m.code : '')))]
  // 去除数组空字符
  menusArr.splice(menusArr.indexOf(''), 1);
  buttonArr.splice(buttonArr.indexOf(''), 1);
  return {
    menusArr: menusArr,
    buttonArr: buttonArr
  };
}

const authMiddleware = async (req, res, next) => {
  try {
    // 获取 token
    const user = await getUserFromToken(req); // 实现token解析
    
    // 获取用户菜单权限
    const btnsAndMenus = await getPermissions(user.id); // 获取用户所有权限code
    // console.log(btnsAndMenus);
    
    // 将用户信息添加到请求对象中
    req.user = { ...user.toJSON(), menus: btnsAndMenus.menusArr, buttons: btnsAndMenus.buttonArr };
    console.log("-----验证权限成功------");

    next();
  } catch (error) {
    // 验证失败，返回错误信息
    sendResponse( res, { code: 401, message: 'Invalid token' });
  }
};

module.exports = { authMiddleware };
